package top.v5it.japi.plus.spring.boot.autoconfigure.properties;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import top.v5it.japi.plus.core.Japi;

import java.util.Set;

/**
 * 应用程序配置
 *
 * @author zhanpu
 * @date 2020-11-20
 */
@Data
@ConfigurationProperties("spring.japi")
public class JapiProperties implements Japi {

    /**
     * 测试
     */
    private String test;

    /**
     * 配置拦截器
     */
    private Interceptor interceptor;

    /**
     * 配置{@link Validator}验证器
     */
    private Validator validator;

    /**
     * 配置Xss拦截器
     */
    private Xss xss;

    /**
     * 应用数据加载进redis缓存所对应的key前缀
     */
    private String cachePrefix;

    /**
     * 应用程序全局超时时间
     */
    private long timeout;

    /**
     * ssl配置
     */
    private Ssl ssl;

    /**
     * 应用http请求或响应时的头部名称前缀
     *
     * @return 头前缀
     */
    @Override
    public String getHeadPrefix() {
        return interceptor.getHeadPrefix();
    }

    /**
     * 应用{@link Validator}验证是否快速失败
     *
     * @return true-快速失败，false-验证所有字段
     */
    @Override
    public boolean isFailFast() {
        return validator.isFailFast();
    }

    /**
     * 应用http请求或响应数据加解密算法(Encryption and decryption algorithm)
     * <pre>
     *     示例：
     *     eada: RSA
     *     eada: AES
     * </pre>
     *
     * @return {@link top.v5it.japi.plus.core.Japi.Eada}
     */
    @Override
    @Deprecated
    public Eada getEada() {
        return interceptor.getEada();
    }

    /**
     * 应用http请求认证类型
     * <pre>
     *     示例：
     *     authorization-type: SHA256-RSA2048
     *     authorization-type: HMAC-SHA256
     * </pre>
     *
     * @return 认证类型
     */
    @Override
    public String getAuthorizationType() {
        return this.interceptor.authorized.getType().getValue();
    }

    /**
     * 应用程序可能会抛出的异常列表，只有当抛出的异常在此列表中时才会捕获并处理输出
     */
    private Set<String> exceptionSet;

    /**
     * 验证器
     */
    @Getter
    public static class Validator {

        /**
         * 应用{@link javax.validation.Validator}时，是否采用快速失败验证模式
         */
        @Setter
        private boolean failFast;
    }

    /**
     * 拦截器配置
     */
    @Getter
    @Setter
    public static class Interceptor {

        /**
         * 应用http请求时需要进行拦截的链接地址
         */
        private String[] includes;

        /**
         * 应用http请求时排除不需要进行拦截并过虑的链接地址
         */
        private String[] excludes;

        /**
         * 应用http请求或响应时的头部名称前缀
         */
        private String headPrefix;

        /**
         * 加解密配置
         */
        private Eada eada;

        /**
         * 认证配置
         */
        private Authorized authorized;

        /**
         * token配置
         */
        private Token token;

        /**
         * 为当前应用程序自定义拦截器配置
         * <pre>
         *     spring:
         *       japi:
         *         interceptor:
         *           properties:
         *             - one: com.xx.interceptor.MyInterceptor
         *               two: 60
         *               three:
         *                 - /xx/yy
         *               four:
         *                 - /zz/qq
         * </pre>
         * one为自定义拦截器类全限定名;two为拦截器执行顺序;three为拦截器要拦截的请求链接地址;four为拦截器需要排除的请求链接地址
         */
//        private Tuple4<String, Integer, String[], String[]>[] properties;
        private Properties[] properties;

        @Getter
        @Setter
        public static class Properties {

            /**
             * 拦截器类
             */
            private String clazz;

            /**
             * 排序
             */
            private Integer order;

            /**
             * 应用http请求时需要进行拦截的链接地址
             */
            private String[] includes;

            /**
             * 应用http请求时排除不需要进行拦截并过虑的链接地址
             */
            private String[] excludes;
        }

        /**
         * 认证配置
         */
        @Getter
        @Setter
        public static class Authorized {

            /**
             * 应用http请求认证类型
             * <pre>
             *     示例：
             *     authorization-type: SHA256-RSA2048
             *     authorization-type: HMAC-SHA256
             * </pre>
             */
            private AuthorizationType type;

            /**
             * nonce在允许范围内不可重复使用，单位秒
             */
            private long timeout;

            /**
             * 客户端与服务端允许范围内的误差时间，单位秒
             */
            private long diffTime;
        }

        /**
         * token配置
         */
        @Getter
        @Setter
        public static class Token {

            /**
             * 应用http请求时需要进行token拦截的链接地址
             */
            private String[] includes;

            /**
             * 应用http请求时排除不需要进行token拦截的链接地址
             */
            private String[] excludes;
        }

    }

    /**
     * XSS拦截配置
     */
    @Getter
    @Setter
    public static class Xss {

        /**
         * 应用http请求时排除不需要XSS拦截并过虑的链接地址（多个用逗号分隔）
         */
        private String exclude;

        /**
         * 是否对富文本进行拦截并过虑
         */
        private boolean includeRichText;

        /**
         * 应用http请求时需要进行拦截并过虑的链接地址
         */
        private String[] includes;

    }

    /**
     * 配置ssl
     */
    @Getter
    @Setter
    public static class Ssl {

        /**
         * 证书文件路径
         */
        private String certFilepath;

        /**
         * 私钥文件路径
         */
        private String privateKeyFilepath;
    }

}
